#include"apue.h"
void login();
void get_cmd(void*);
int pasv_fun();
void ls_al(int quickfd);
void cd(char* cmd,int len);
void get_file(char* cmd,int len);
void put_file(char* cmd,int len);
typedef struct sockaddr* sp;
int sockfd;

int main()
{
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	DIR* dp;
	struct dirent* ep;
	char buf[1024] = {};
	if(0 > sockfd)
	{
		perror("socket");
		return -1;
	}

	struct sockaddr_in addr = {AF_INET};
	addr.sin_port = htons(21);
	addr.sin_addr.s_addr = inet_addr("192.168.6.66");

	int ret = connect(sockfd,(sp)&addr,sizeof(addr));
	if(0 > ret)
	{
		perror("connect");
		return -1;
	}
	login();
	pthread_t tid;
	pthread_create(&tid,NULL,(void*)&get_cmd,NULL);
	pthread_join(tid,NULL);
	//pasv_fun(sockfd);
	close(sockfd);
}
int pasv_fun()
{
	static int port=0;
	static int newsockfd=0;
	int newport=pasv(sockfd);
	printf("newport:%d\n",newport);
	if(newport!=port)
	{
		newsockfd=socket(AF_INET,SOCK_STREAM,0);
		if (0>newsockfd)
		{
			perror("socket");
			return -1;/* code */
		}

	 	struct sockaddr_in addr={AF_INET};
		addr.sin_port=htons(newport);
		addr.sin_addr.s_addr=inet_addr("192.168.6.66");
		int ret=connect(newsockfd,(sp)&addr,sizeof(addr));
		if (0>ret)
		{
			perror("connect");
			return -1;
		/* code */
		}
		port=newport;
	}
	return newsockfd;



	//printf("server:%s\n",buf);
}
void get_cmd(void* arg)
{
	static int fdchange_flag=0;
	char cmd[1024]={};
	int cmd_result;
	static int quickfd=0;
	while(1)
	{
		bzero(cmd,sizeof(cmd));
		printf("ftp->");
		gets(cmd);
		cmd_result=ftp_cmd_analyse(cmd);
		switch(cmd_result)
		{
			case CMD_ERROR:
			printf("CMDERROR!\n");
			break;
			case CMD_LS:
			{
				
				quickfd=pasv_fun();
				
				
				//printf("-----ls pthread:%d %d\n",quickfd,fdchange_flag);
				ls_al(quickfd);
				break;
			}
			case CMD_CD:

			cd(cmd,strlen(cmd));
			
			break;
			case CMD_GET:
			get_file(cmd,strlen(cmd));
			break;
			case CMD_PUT:
			put_file(cmd,strlen(cmd));
			break;
			case CMD_QUIT:
			pthread_exit(0);
		}

	}
	
}
void login()
{

	char buf[1024]={};
	recv(sockfd,buf,sizeof(buf),0);
	printf("serve:%s\n",buf);
	memset(buf,0,sizeof(buf));
	//gets(buf);
	char buf1[1024]={};
	sprintf(buf1,"USER %s\n",buf);

	send(sockfd,"USER EOS1806\n",13,0);
	memset(buf,0,1024);
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
	memset(buf,0,1024);
	memset(buf1,0,1024);
	//gets(buf);
	sprintf(buf1,"PASS %s\n",buf);
	send(sockfd,"PASS iqot1806\n",14,0);
	memset(buf,0,1024);
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
	if(strncmp(buf,"230 Login successful.",21)!=0)
	{
		printf("passwd error!\n");
		exit(0);
	}
	send(sockfd,"SYST\n",5,0);
	memset(buf,0,1024);
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
	memset(buf,0,1024);
	send(sockfd,"PWD\n",4,0);
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
}
void put_file(char* cmd,int len)
{
	
	char dir[255]={};
	char buf[1024]={};
	
	//char bufsize[255]={};
	char time[255]={};
	strncpy(dir,cmd+4,len-3);
	//send(sockfd,"TYPE A\n",7,0);
	//recv(sockfd,buf,sizeof(buf),0);
	//printf("server:%s\n",buf);
	//bzero(buf,255);
	sprintf(buf,"SIZE %s\n",dir);
	send(sockfd,buf,strlen(buf),0);
	recv(sockfd,buf,sizeof(buf),0);
	//strcpy(bufsize,buf);
	//printf("server:%s\n",buf);
	
	int datafd=pasv_fun();
	printf("datafd:%d\n",datafd);
	//bzero(buf,sizeof(buf));
	//recv(sockfd,buf,sizeof(buf),0);
	//printf("server:%s\n",buf);
	bzero(buf,sizeof(buf));

	
	int fd=open(dir,O_RDWR,0666);
	if(0>fd)
	{
		perror("open");
		return ;
	}
	sprintf(buf,"STOR %s\n",dir);
	send(sockfd,buf,strlen(buf),0);
	//bzero(buf,sizeof(buf));
	
	
	
	while(read(fd,buf,sizeof(buf)!=0))
	{
		send(datafd,buf,sizeof(buf),0);
		bzero(buf,sizeof(buf));
	}


	bzero(buf,sizeof(buf));
	recv(sockfd,buf,strlen(buf),0);
	printf("server:%s\n",buf);
	bzero(buf,sizeof(buf));

	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
	//bzero(buf,sizeof(buf));

	close(fd);
	printf("upload success!\n");
	
}
void get_file(char* cmd,int len)
{
	
	char dir[255]={};
	char buf[1024]={};
	
	char bufsize[255]={};
	char time[255]={};
	strncpy(dir,cmd+4,len-3);
	send(sockfd,"TYPE A\n",7,0);
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
	bzero(buf,255);
	sprintf(buf,"SIZE %s\n",dir);
	send(sockfd,buf,strlen(buf),0);
	recv(sockfd,buf,sizeof(buf),0);
	strcpy(bufsize,buf);
	printf("server:%s\n",buf);
	//printf("+++++++++++\n");
	bzero(buf,255);
	sprintf(buf,"MDTM %s\n",dir);
	//printf("---------------\n");
	send(sockfd,buf,strlen(buf),0);
	recv(sockfd,buf,sizeof(buf),0);

	strcpy(time,buf);
	printf("server:%s\n",buf);
	//int quickfd=pasv_fun();
	//printf("---------------\n");
	int datafd=pasv_fun();
	printf("datafd:%d\n",datafd);
	//bzero(buf,sizeof(buf));
	//recv(sockfd,buf,sizeof(buf),0);
	//printf("server:%s\n",buf);
	bzero(buf,sizeof(buf));

	
	int fd=open(dir,O_CREAT|O_EXCL|O_RDWR|O_TRUNC,0666);
	if(0>fd)
	{
		perror("open");
		return ;
	}
	sprintf(buf,"RETR %s\n",dir);
	send(sockfd,buf,strlen(buf),0);
	//bzero(buf,sizeof(buf));
	
	
	int ret = 0;
	while((ret = recv(datafd,buf,sizeof(buf),0))>0)
	{
		write(fd,buf,strlen(buf));
		bzero(buf,sizeof(buf));
	}


	bzero(buf,sizeof(buf));
	recv(sockfd,buf,strlen(buf),0);
	printf("server:%s\n",buf);
	bzero(buf,sizeof(buf));

	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
	//bzero(buf,sizeof(buf));

	close(fd);
	printf("dowload success!\n");
	get_time(dir,sizeof(dir),time,sizeof(time));
	
}
void cd(char* cmd,int len)
{
	
	char buf[255]={};
	char dir[255]={};
	strncpy(dir,cmd+3,len-2);
	//printf("--------------\n");
	
	//memset(buf,0,1024);
	sprintf(buf,"CWD %s\n",dir);
	send(sockfd,buf,strlen(buf),0);
	//memset(buf,0,1024);
	//bzero(buf,1024);
	recv(sockfd,buf,sizeof(buf),0);
	//printf("++++++++++++\n");
	printf("server:%s\n",buf);
	send(sockfd,"PWD\n",4,0);
	//bzero(buf,1024);
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);

	

}
void ls_al(int quickfd)
{
	//printf("%d\n",quickfd);
	if(quickfd==-1)
	{
		printf("error port!\n");

		pthread_exit(0);
	}			
	
	char buf[4096]={};
	//bzero(buf,4096);
	//printf("+++++++++++++++++++++++\n");
	send(sockfd,"LIST -al\n",9,0);
	//printf("send----\n");
	//printf("+++++++++++++++++++++++\n");	
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
	bzero(buf,4096);
	recv(quickfd,buf,sizeof(buf),0);
	printf("%s\n",buf);
	//printf("-----sockfd:%d quickfd:%d\n", sockfd,quickfd);
	bzero(buf,sizeof(buf));
	sleep(1);
	//printf("----second recv\n");
	recv(sockfd,buf,sizeof(buf),0);
	printf("server:%s\n",buf);
}
